package reflect;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class ReflectDemo3 {
    //Method成员方法相关方法
    public static void main(String[] args) throws Exception  {
        //1. 获取Student.java文件
        Class clazz = Class.forName("reflect.Student");
        //2. 获取ageMethod方法对象
        Method ageMethod = clazz.getMethod("setAge", int.class);
        System.out.println("equals方法对象：" + ageMethod);
        //3.获取ageMethod方法权限修饰符魔法值
        System.out.println("ageMethod方法权限修饰符魔法值= " + ageMethod.getModifiers());
        System.out.println("ageMethod方法权限修饰符= " + Modifier.toString(ageMethod.getModifiers()));
        System.out.println("-------------------------------");
        //4.获取ageMethod方法返回值类型
        System.out.println("ageMethod方法返回值类型：" + ageMethod.getReturnType());
        //5.获取ageMethod方法名
        System.out.println("ageMethod方法名：" + ageMethod.getName());
        System.out.println("-------------------------------");
        //6.获取ageMethod方法形参列表
        Class[] parameterTypes = ageMethod.getParameterTypes();
        for (Class parameterType : parameterTypes) {
            System.out.println("ageMethod方法形参列表：" + parameterType);
        }
        System.out.println("-------------------------------");
        //7.获取形参个数
        System.out.println("ageMethod方法形参个数：" + ageMethod.getParameterCount());
        //8. 执行该方法
        // 打开暴力访问开关
        ageMethod.setAccessible(true);
        Student s = new Student();
        ageMethod.invoke(s, 30);
        System.out.println("修改后的ageMethod方法age值：" + s.getAge());
        // 获取stu对象的age值
        Method getAgeMethod = clazz.getMethod("getAge");
        getAgeMethod.setAccessible(true);
        int invoke = (int) getAgeMethod.invoke(s);
        System.out.println("age属性的值为：" + invoke);//30
    }

    //Constructor成员变量相关方法
    public static void main3(String[] args) throws Exception {
        //1.获取类对象
        Class clazz = Class.forName("reflect.Student");
        //2.获取一个满参构造方法
        Constructor fullCon = clazz.getDeclaredConstructor(String.class, int.class, double.class, int.class);
        //3.获取该构造方法的权限修饰符魔法值
        System.out.println("满参权限魔法值" + fullCon.getModifiers());
        //4.获取名称
        System.out.println("满参构造名：" + fullCon.getName());
        //5. 获取该构造方法的形参的个数
        System.out.println("满参构造的形参个数：" + fullCon.getParameterCount());
        //6. 获取该构造方法的形参的类型
        Class[] parameterTypes = fullCon.getParameterTypes();
        for (Class parameterType : parameterTypes) {
            System.out.println("满参构造的形参类型：" + parameterType);
        }
        System.out.println("-------------------------------");
        //7. 执行该构造方法对象并创建实例化对象
        fullCon.setAccessible( true);//打开暴力访问开关
        Student s = (Student) fullCon.newInstance("张三", 18, 90.0, 1000);
        System.out.println("创建的实例对象为：" + s);
    }
    //Field变量的相关方法
    public static void main1(String[] args) throws Exception {
        //1.获取类对象
        Class clazz = Class.forName("reflect.Student");
        //2.获取一个公开属性
        Field ageField = clazz.getField("age");
        System.out.println("age的权限修饰符为： " + Modifier.toString(ageField.getModifiers()));
        System.out.println("--------------------------");

        //3.获取该属性的对象类型
        System.out.println("该属性的对象类型为：" + ageField.getType());
        System.out.println("-------------------------------");

        //4.获取该属性对象的名称
        System.out.println("该属性对象的名称为：" + ageField.getName());
        System.out.println("-------------------------------");

        // 5. 获取该属性对象的属性值
        ageField.setAccessible(true);
        Student s = new Student("张三", 18);
        System.out.println("该属性对象的属性值为：" + ageField.get(s));
        // 6. 修改当前对象的,这个age属性的值为：30
        ageField.set(s, 30);
        System.out.println("修改后的属性对象的属性值为：" + ageField.get(s));
        System.out.println("-------------------------------");
        // 8. 获取name属性对象
        Field name = clazz.getDeclaredField("name");
        //打开暴力访问开关
        name.setAccessible(true);
        System.out.println("name属性对象的属性值为：" + name.get(s));
        //9.获取学生对象的所有值
        String s1 = (String) name.get(new Student("李四", 18, 90.0, 1000));
        System.out.println("学生对象name属性的值为：" + s1);
        name.set(s, "王五");
    }
}
